#include "stdafx.h"

#include "Lib2D/SpriteInstance.h"
#include "Lib2D/Sprite.h"
//#include "Lib2D/Rect.h"
#include "Lib2D/Font.h"
#include "Core/DEF.h"

using namespace irr;
using namespace irr::core;

////////////////////////////////////////////////////////////////////////////////////////////////////
void CSpriteInstance::InitInstance( s32 posX, s32 posY, CSprite* pSpr )
{
	m_pSpr = pSpr;

	_posX = (posX);
	_posY = (posY);

	_nOldX = 0;
	_nOldY = 0;

	_pos_ox = 0;
	_pos_oy = 0;

	_flags = 0;

	_nCrtAnim = 0;
	_nCrtAFrame = 0;
	_nPrevAFrame = -1;
	_nCrtTime = 0;
	_nCrtPal = 0;
	_nMap = 0;
	_fScale = 1.0f;

	m_UpdateTime = 0.f;
	m_isEnded = false;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
CSpriteInstance::CSpriteInstance()
{
	InitInstance(0,0,NULL);
}

////////////////////////////////////////////////////////////////////////////////////////////////////

CSpriteInstance::CSpriteInstance(s32 posX, s32 posY, CSprite* pSpr)
{
	InitInstance(posX,posY,pSpr);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
CSpriteInstance::~CSpriteInstance()
{

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CSpriteInstance::UpdateSpriteAnim(float ts)
{
	if (m_pSpr == NULL)
		return;

	if (_nCrtTime < 0)
		return;

	int time = m_pSpr->GetAFrameTime(_nCrtAnim, _nCrtAFrame);

	if (time == 0)
		return;

	m_UpdateTime += ts;

	int updateTime = 0;
	while( m_UpdateTime > DEF::FIXXED_UPDATE_TIME )
	{
		_nCrtTime++;
		//m_UpdateTime = 0.f;
		m_UpdateTime -= DEF::FIXXED_UPDATE_TIME;
		updateTime++;
	}
	
	_nPrevAFrame = _nCrtAFrame;

	if (time > _nCrtTime)
		return;

	_nCrtTime = 0;

	//_nCrtAFrame++;
	_nCrtAFrame += updateTime;

	if (_nCrtAFrame >= m_pSpr->GetAFrames(_nCrtAnim))
	{
		_nCrtAFrame = 0;
		_pos_ox = 0;
		_pos_oy = 0;
		m_isEnded = true;
	}

	if ((_flags & FLAG_APPLY_ANIM_OFFSET) != 0)
		ApplyAnimOff();
}
////////////////////////////////////////////////////////////////////////////////////////////////////

void CSpriteInstance::UpdateAnim(float ts)
{
	//if (IsAnimEnded() && ((_flags & FLAG_LOOP_FOREVER) == 0))
	//{
	//
	//}
	//else
	{
		UpdateSpriteAnim(ts);
	}
}
////////////////////////////////////////////////////////////////////////////////////////////////////

void CSpriteInstance::PaintAnimOnScreen(int posX, int posY , int alpha)
{
	irr::f32 fOldSize = m_pSpr->GetScale();
	m_pSpr->SetScale(_fScale);
	if (_nCrtTime >= 0)
		m_pSpr->PaintAFrame(_nCrtAnim, _nCrtAFrame, posX, posY, _flags, alpha);
	else if (_nCrtAnim >= 0) // _nCrtAnim --> module
		m_pSpr->PaintModule(_nCrtAnim, posX, posY, _flags, alpha);
	else if (_nCrtAFrame >= 0) // _nCrtAFrame --> frame
		m_pSpr->PaintFrame(_nCrtAFrame, posX, posY, _flags, alpha);
	m_pSpr->SetScale(fOldSize);
}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CSpriteInstance::PaintAnim(int alpha)
{
	if (m_pSpr == NULL)
		return;
	
	PaintAnimOnScreen(_posX , _posY, alpha);
}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CSpriteInstance::ApplyAnimOff()
{
	int old_pos_ox = _pos_ox;
	int old_pos_oy = _pos_oy;
	//_posX -= _pos_ox;
	//_posY -= _pos_oy;

	//////////

	_pos_ox = m_pSpr->GetAFrameOffsetX(_nCrtAnim, _nCrtAFrame);
	if ((_flags & FLAG_FLIP_X) != 0) _pos_ox = -_pos_ox;

	_pos_oy = m_pSpr->GetAFrameOffsetY(_nCrtAnim, _nCrtAFrame);
	if ((_flags & FLAG_FLIP_Y) != 0) _pos_oy = -_pos_oy;

	//////////

	//_posX += _pos_ox;
	//_posY += _pos_oy;


	_posX += _pos_ox - old_pos_ox;
	_posY += _pos_oy - old_pos_oy;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CSpriteInstance::SetAnim(s32 id)
{
	if (id != _nCrtAnim)
	{
		_nCrtAnim	= (s16)id;
		Restart();
	}
	m_isEnded = false;
}

void CSpriteInstance::Restart()
{
	_nPrevAFrame = -1;
	_nCrtAFrame	= 0;
	_nCrtTime	= 0;

	_pos_ox = 0;
	_pos_oy = 0;
	m_isEnded = false;

	if ((_flags & FLAG_APPLY_ANIM_OFFSET) != 0)
		ApplyAnimOff();
}

void CSpriteInstance::SetAnimSafe(irr::s32 id)
{
	if (id != _nCrtAnim)
	{
		_nCrtAnim = (s16)id;		
	}
	m_isEnded = false;
		
	Restart();	
}

////////////////////////////////////////////////////////////////////////////////////////////////////

bool CSpriteInstance::IsAnimEnded()
{
	//if(_nCrtAFrame == 0 && _pos_ox == 0 && _pos_oy == 0 /*&& (_flags & FLAG_LOOP_FOREVER) == 0)*/)
	//	return true;
	if(m_isEnded)
		return true;

	if (_nCrtAFrame != m_pSpr->GetAFrames(_nCrtAnim) - 1)
		return false;

	int time = m_pSpr->GetAFrameTime(_nCrtAnim, _nCrtAFrame);

	return ((time == 0) || (_nCrtTime == time - 1));
}

///////////////////////////////////////////////////////////////////////////////////////////
//
void CSpriteInstance::Paint()
{
	PaintAnim();
}

///////////////////////////////////////////////////////////////////////////////////////////

void CSpriteInstance::Paint(const vector3df& pos)
{
	ASSERT(m_pSpr);
	irr::f32 fOldSize = m_pSpr->GetScale();
	m_pSpr->SetScale(_fScale);

	if (_nCrtTime >= 0)
		m_pSpr->PaintAFrame(_nCrtAnim, _nCrtAFrame, pos, _flags);
	else if (_nCrtAnim >= 0) // _nCrtAnim --> module
		m_pSpr->PaintModule(_nCrtAnim, pos, _flags);
	else if (_nCrtAFrame >= 0) // _nCrtAFrame --> frame
		m_pSpr->PaintFrame(_nCrtAFrame, pos, _flags);
	m_pSpr->SetScale(fOldSize);
}

///////////////////////////////////////////////////////////////////////////////////////////
//
void CSpriteInstance::Update(float ts)
{	

	if ((_flags & FLAG_HIDDEN) != 0)
		return;

	if ((_flags & FLAG_PAUSED) != 0)
		return;

	_nOldX = _posX;
	_nOldY = _posY;

	UpdateAnim(ts);
	
}

void CSpriteInstance::SetPosition(irr::s32 posX, irr::s32 posY)
{
	_posX = posX;
	_posY = posY;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
